<?php

namespace app\common\service;

class YoudaoVocalService extends ApiService
{

    private $appKey;
    private $appSecret;
    private $enVoiceId;
    private $apiUrl;


    public function __construct()
    {
        $this->appKey = env('YOUDAO.YOUDAO_APP_KEY', '');
        $this->appSecret = env('YOUDAO.YOUDAO_APP_SECRET', '');
        $this->enVoiceId = env('YOUDAO.YOUDAO_EN_VOICE_ID', '');
        $this->apiUrl = 'https://openapi.youdao.com/ttsapi';
    }

    public function getEnVocalToByte(string $word)
    {
        return $this->getTTSapiDictByte($word, $this->enVoiceId);
    }

    public function getTTSapiDictByte($word, string $voiceName, int|float $speed = null)
    {
        $params = [
            'q' => $word,
            'voiceName' => $voiceName ?? $this->enVoiceId,
            'format' => 'mp3',
            'speed' => $speed ?? 1
        ];
        $params = $this->add_auth_params($params, $this->appKey, $this->appSecret);
        $res = HttpService::postRequest($this->apiUrl, $params);
        if (!$res) {
            logSave([
                'file' => __FILE__,
                'res'=>$res,
                'message' => '语音合成生成失败'
            ], 'getEnVocalToByte');
            $this->setError('语音合成生成失败');
            return false;
        }
        if (isJson($res)) {
            $res = json_decode($res, true);
            logSave([
                'file' => __FILE__,
                'res'=>$res,
                'message' => '语音合成生成失败'
            ], 'getEnVocalToByte');
            $this->setError('语音合成生成失败;错误码：' . $res['errorCode']);
            return false;
        }
        return $res;
    }


    public function add_auth_params($param, $appKey, $appSecret)
    {
        if (array_key_exists('q', $param)) {
            $q = $param['q'];
        } else {
            $q = $param['img'];
        }
        $salt = $this->create_uuid();
        $curtime = strtotime("now");
        $sign = $this->calculate_sign($appKey, $appSecret, $q, $salt, $curtime);
        $param['appKey'] = $appKey;
        $param['salt'] = $salt;
        $param["curtime"] = $curtime;
        $param['signType'] = 'v3';
        $param['sign'] = $sign;
        return $param;
    }

    public function create_uuid()
    {
        $str = md5(uniqid(mt_rand(), true));
        $uuid = substr($str, 0, 8) . '-';
        $uuid .= substr($str, 8, 4) . '-';
        $uuid .= substr($str, 12, 4) . '-';
        $uuid .= substr($str, 16, 4) . '-';
        $uuid .= substr($str, 20, 12);
        return $uuid;
    }

    public function calculate_sign($appKey, $appSecret, $q, $salt, $curtime)
    {
        $strSrc = $appKey . $this->get_input($q) . $salt . $curtime . $appSecret;
        return hash("sha256", $strSrc);
    }

    public function get_input($q)
    {
        if (empty($q)) {
            return null;
        }
        $len = mb_strlen($q, 'utf-8');
        return $len <= 20 ? $q : (mb_substr($q, 0, 10) . $len . mb_substr($q, $len - 10, $len));
    }

}